// 实现

#include "contact.h"

// 静态初始化
// void InitContact(Contact *pc)
// {
//     assert(pc);
//     memset(pc->data, 0, sizeof(pc->data));
//     pc->sz = 0;
// }

// 动态初始化
// void InitContact(Contact *pc)
// {
//     assert(pc);
//     pc->sz = 0;
//     pc->capacity = DEFAULT_SZ;
//     pc->data = (PeoInfo *)calloc(pc->capacity, sizeof(PeoInfo));
//     if (pc->data == NULL)
//     {
//         perror("calloc fail");
//         return;
//     }
// }

// 文件版本初始化
void InitContact(Contact *pc)
{
    assert(pc);
    pc->sz = 0;
    pc->capacity = DEFAULT_SZ;
    pc->data = (PeoInfo *)calloc(pc->capacity, sizeof(PeoInfo));
    if (pc->data == NULL)
    {
        perror("calloc fail");
        return;
    }
    // 加载文件中的信息到通讯录
    LoadContact(pc);
}

//  静态版本
//  void AddContact(Contact *pc)
//  {
//      assert(pc);
//      if (pc->sz == MAX)
//      {
//          printf("通讯录已满，无法增加\n");
//          return;
//      }
//      // 增加信息
//      printf("请输入名字:\n");
//      scanf("%s", pc->data[pc->sz].name);
//      printf("请输入年龄:\n");
//      scanf("%d", &pc->data[pc->sz].age);
//      printf("请输入性别:\n");
//      scanf("%s", pc->data[pc->sz].sex);
//      printf("请输入电话:\n");
//      scanf("%s", pc->data[pc->sz].tele);
//      printf("请输入地址:\n");
//      scanf("%s", pc->data[pc->sz].addr);
//      pc->sz++;
//      printf("增加成功\n");
//  }

void CheckCapacity(Contact *pc)
{
    assert(pc);
    if (pc->sz == pc->capacity)
    {
        PeoInfo *tmp = realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
        if (tmp == NULL)
        {
            perror("realloc fail");
            return;
        }
        pc->data = tmp;
        pc->capacity += 2;
        printf("增容成功\n");
    }
}
void AddContact(Contact *pc)
{
    assert(pc);
    CheckCapacity(pc);
    printf("请输入名字\n");
    scanf("%s", pc->data[pc->sz].name);
    printf("请输入年龄\n");
    scanf("%d", &pc->data[pc->sz].age);
    printf("请输入性别\n");
    scanf("%s", pc->data[pc->sz].sex);
    printf("请输入电话\n");
    scanf("%s", pc->data[pc->sz].tele);
    printf("请输入地址\n");
    scanf("%s", pc->data[pc->sz].addr);
    pc->sz++;
}
void ShowContact(const Contact *pc)
{
    assert(pc);
    if (pc->sz == 0)
    {
        printf("通讯录为空，无需打印\n");
        return;
    }
    printf("%-20s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");
    for (int i = 0; i < pc->sz; i++)
    {
        // 打印每个人的信息
        printf("%-18s%-4d%-4s%-10s%-30s\n",
               pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
    }
}

int FindByName(Contact *pc, char name[])
{
    assert(pc);
    for (int i = 0; i < pc->sz; i++)
    {
        if (strcmp(name, pc->data[i].name) == 0)
        {
            return i;
        }
    }
    return -1;
}

void DelContact(Contact *pc)
{
    assert(pc);
    char name[NAME_MAX];
    if (pc->sz == 0)
    {
        printf("通讯录为空，无法删除\n");
        return;
    }
    printf("请输入要删除的名字:\n");
    scanf("%s", name);
    int ret = FindByName(pc, name);
    if (ret == -1)
    {
        printf("要删除的人不存在\n");
        return;
    }
    for (int i = ret; i < pc->sz; i++)
    {
        pc->data[i] = pc->data[i + 1];
    }
    pc->sz--;
}

void SearchContact(Contact *pc)
{
    assert(pc);
    char name[NAME_MAX];
    printf("请输入要查找的名字:\n");
    scanf("%s", name);
    int ret = FindByName(pc, name);
    if (ret == -1)
    {
        printf("要查找的人不存在\n");
        return;
    }
    printf("%-20s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");
    printf("%-20s%-5d%-5s%-12s%-30s\n",
           pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tele, pc->data[ret].addr);
}

void ModifyContact(Contact *pc)
{
    char name[NAME_MAX];
    assert(pc);
    printf("请输入要修改人的名字:");
    scanf("%s", name);
    int ret = FindByName(pc, name);
    if (ret == -1)
    {
        printf("要修改的人不存在\n");
        return;
    }
    // 修改
    printf("请输入名字:");
    scanf("%s", pc->data[ret].name);
    printf("请输入年龄:");
    scanf("%d", &(pc->data[ret].age));
    printf("请输入性别:");
    scanf("%s", pc->data[ret].sex);
    printf("请输入电话:");
    scanf("%s", pc->data[ret].tele);
    printf("请输入地址:");
    scanf("%s", pc->data[ret].addr);
}
void DestroyContact(Contact *pc)
{
    assert(pc);
    free(pc->data);
    pc->data = NULL;
    pc->capacity = pc->sz = 0;
}
void SaveContact(Contact *pc)

{
    assert(pc);
    // 以写的形式打开文件
    FILE *pf = fopen("contact.txt", "wb");
    if (pf == NULL)
    {
        perror("SaveContact fail");
        return;
    }
    // 写数据
    for (int i = 0; i < pc->sz; i++)
    {
        fwrite(&pc->data[i], sizeof(PeoInfo), 1, pf);
    }
    fclose(pf);
    pf = NULL;
}
void LoadContact(Contact *pc)
{
    assert(pc);
    FILE *pf = fopen("contact.txt", "rb");
    if (pf == NULL)
    {
        perror("LoadContact fail");
        return;
    }
    // 读文件
    PeoInfo tmp = {0};
    // fread读到一个数据返回1，读不到返回0
    while (fread(&tmp, sizeof(PeoInfo), 1, pf))
    {
        CheckCapacity(pc);
        pc->data[pc->sz] = tmp;
        pc->sz++;
    }

    fclose(pf);
    pf = NULL;
}